﻿using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;

namespace HandyControl.Tools.Interop;

internal sealed class SafeFileMappingHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    [SecurityCritical]
    internal SafeFileMappingHandle(IntPtr handle) : base(false)
    {
        SetHandle(handle);
    }

    [SecurityCritical, SecuritySafeCritical]
    internal SafeFileMappingHandle() : base(true)
    {
    }

    public override bool IsInvalid
    {
        [SecurityCritical, SecuritySafeCritical]
        get => handle == IntPtr.Zero;
    }

    [SecurityCritical, SecuritySafeCritical]
    protected override bool ReleaseHandle()
    {
        new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
        try
        {
            return CloseHandleNoThrow(new HandleRef(null, handle));
        }
        finally
        {
            CodeAccessPermission.RevertAssert();
        }
    }

    [SecurityCritical]
    public static bool CloseHandleNoThrow(HandleRef handle)
    {
        HandleCollector.Remove((IntPtr) handle, CommonHandles.Kernel);
        var result = InteropMethods.IntCloseHandle(handle);
        return result;
    }
}
